﻿using System;
using System.Collections.Generic;
using System.Xml.Linq;
using EzDesk.Core.Data;
using EzDesk.Utility.EzML;
using EzDesk.Core.Model;
using EzDesk.Utility.Json;
using EzDesk.Core.Interface;
using EzDesk.Utility.Log;
using System.Linq;

namespace EzDesk.Core.ServiceImpl.Services
{
    public partial class CoreClientService : ICoreClientService
    {
        #region [ Feed Methods ]
        
        public string GetXmlFeedsBetweenDate(string feedTypeStr, Guid userId, DateTime from, DateTime to, bool? isRead, bool? isAvaiable, bool? isMark)
        {
            // todo: 默认情况下 每次最多给返回50个
            var feeds = _coreService.GetFeeds(feedTypeStr, userId, from, to, 50, isRead, isAvaiable, isMark);
            foreach (var feed in feeds)
            {
                feed.IconUrl = getIconUrl(feed.Icon);
            }
            return generateFeedsXml(feeds, userId);
        }
        public string GetXmlFeedsByCount(string feedTypeStr, Guid userId, int startIndex, int count, bool? isRead, bool? isAvaiable, bool? isMark)
        {
            var feeds = _coreService.GetFeeds(feedTypeStr, userId, startIndex, count, isRead, isAvaiable, isMark);
            //todo: 重构。。
            foreach (var feed in feeds)
            {
                feed.IconUrl = getIconUrl(feed.Icon);
            }
            return generateFeedsXml(feeds, userId);
        }

        public string GetAllXmlFeedsBetweenDate(Guid userId, DateTime from, DateTime to, bool? isRead, bool? isAvaiable, bool? isMark)
        {
            var allFeeds = getAllFeeds(
                feedType => _coreService.GetFeeds(feedType, userId, from, to, 50, isRead, isAvaiable, isMark)
                );
            return generateFeedsXml(allFeeds, userId);
        }
        public string GetAllXmlFeedsByCount(Guid userId, int startIndex, int count, bool? isRead, bool? isAvaiable, bool? isMark)
        {
            var allFeeds = getAllFeeds(
                feedType => _coreService.GetFeeds(feedType, userId, startIndex, count, isRead, isAvaiable, isMark)
                );
            return generateFeedsXml(allFeeds, userId);
        }

        public void UpdateFeedStatus(IList<FeedStatus> feedStatus, string memberString)
        {
            _coreService.UpdateFeedStatus(feedStatus, memberString);
        }

        public void SetUserStatus(Guid userId, Guid feedId)
        {
            var currentStatus = getCurrentUserStatus(userId);

            EzDeskDatabaseContainer.GoAndSave(
                container =>
                    {
                        if (currentStatus != null)
                        {
                            container.UserStatusSet.Attach(currentStatus);
                            currentStatus.FeedId = feedId;
                        }
                        else
                        {
                            var newObject = new UserStatus()
                                                {
                                                    CreateOn = DateTime.Now,
                                                    FeedId = feedId,
                                                    UserId = userId
                                                };
                            container.UserStatusSet.AddObject(newObject);
                        }
                    });
        }

        public Guid GetUserStatus(Guid userId)
        {
            var currentStatus = getCurrentUserStatus(userId);
            return currentStatus == null ? Guid.Empty : currentStatus.FeedId;
        }
        #endregion


        private UserStatus getCurrentUserStatus(Guid userId)
        {
            return EzDeskDatabaseContainer.Go(
                entity => entity.UserStatusSet.Where(p => p.UserId == userId).FirstOrDefault());
        }

        #region [ private methods ]
        private IEnumerable<Feed> getAllFeeds(Func<string, IList<Feed>> func)
        {
            var allFeedTypes = FeedTypeDictionary.AllFeedTypes();
            var allFeeds = new List<Feed>();
            allFeedTypes.ForEach(
                feedType =>
                {
                    var feeds = func(feedType);
                    allFeeds.AddRange(feeds);
                });
            return allFeeds;
        }

        private string generateFeedsXml(IEnumerable<Feed> feeds, Guid userId)
        {
            var feedItems = new XElement("feeditems");

            var root = new XElement("root");
            root.Add(new XAttribute("appportalurl", "http://" + this.GetClientBaseUrl()));
            root.Add(feedItems);

            int count = 0;
            
            foreach (var feed in feeds)
            {
                var feedTypeStr = FeedTypeDictionary.IntTypeToString(feed.FeedType);

                string feedDataStr = feed.FeedData;
                IDictionary<string, string> originalfeedData =
                        JsonHelper.JsonToDictionary(feed.FeedData);

                IDictionary<string, string> extraFeedData =
                    JsonHelper.JsonToDictionary(_coreService.GetPersonalFeedData(userId, feed.Id));
                if (extraFeedData != null && extraFeedData.Count > 0)
                {
                    // 合并数据
                    foreach (var keyPair in extraFeedData)
                    {
                        if (originalfeedData.ContainsKey(keyPair.Key))
                        {
                            originalfeedData[keyPair.Key] = keyPair.Value;
                        }
                        else
                        {
                            originalfeedData.Add(keyPair);
                        }
                    }

                    feedDataStr = JsonHelper.ConvertToJson(originalfeedData);
                }

                var feedTemplate = _coreService.GetFeedTemplateById(feed.TemplateId);
                if (feedTemplate == null)
                {
                    LogEx.TRACE("CoreClientService_Feed", "FeedTemplate找不到： " + feed.TemplateId);
                    continue; // 如果feedTemplate不存在 直接忽略这一条
                }

                string feedTitle = EzMLHelper.MergeDataToEzML(
                    feedTemplate.Title,
                    originalfeedData
                    );

                string feedBody = EzMLHelper.MergeDataToEzML(
                    feedTemplate.Body,
                    originalfeedData
                    );

                feed.IconUrl = getIconUrl(feedTemplate.TemplateIconName);

                var feedItem = new XElement("feeditem");
                feedItem.Add(new XAttribute("guid", feed.Id.ToString()));
                feedItem.Add(new XAttribute("createon", feed.CreateOn));
                feedItem.Add(new XAttribute("updateon", feed.UpdateOn));
                feedItem.Add(new XAttribute("type", feedTypeStr));
                feedItem.Add(new XAttribute("isread", feed.IsRead.GetValueOrDefault()));
                feedItem.Add(new XAttribute("isavailable", feed.IsAvailable.GetValueOrDefault()));
                feedItem.Add(new XAttribute("ismark", feed.IsMark.GetValueOrDefault()));
                feedItem.Add(new XAttribute("lastchangeon", feed.LastChangeOn));
                feedItem.Add(new XAttribute("iconurl", feed.IconUrl));

                feedItem.Add(new XElement("data", new XCData(feedDataStr)));

                feedItem.Add(new XElement("title", new XCData(feedTitle)));
                feedItem.Add(new XElement("body", new XCData(feedBody)));

                feedItems.Add(feedItem);
                count++;
            }

            feedItems.Add(new XAttribute("count", count));

            return root.ToString(); ;
                        
        }
        #endregion


    }
}
